{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "368f4908-065c-498a-8dc9-661c2f645d28",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 安装库\n",
    "# pip install pyunit-time\n",
    "# pip install dateparser\n",
    "# pip install jionlp  \n",
    "# pip install sinan\n",
    "# pip install timeworker"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "21714b9d-ffbf-49ea-a67b-11c28a8e211e",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2023-09-17 20:15:00\n",
      "2021-09-30 20:30:00\n",
      "2023-07-15 20:15:00\n",
      "2023-09-15 20:15:00\n",
      "2023-06-01 21:15:00\n",
      "2023-09-15 12:15:00\n",
      "2024-02-10 20:15:00\n",
      "2024-11-28 20:15:00\n",
      "2023-10-02 07:30:00\n",
      "2024-01-20 20:15:00\n",
      "2019-12-01 20:15:00\n",
      "2015-09-15 20:15:00\n",
      "2023-09-18 20:15:00\n",
      "2023-09-18 15:15:00\n",
      "2023-09-18 16:15:56\n"
     ]
    }
   ],
   "source": [
    "# 使用 pyunit-time 解析日期和时间（输入一个基准日期时间，再输入一句中文语句，自动解析语句所表达的下一个日期时间）\n",
    "# 可解析的类型：\n",
    "# 1. 年、月、日、时、分、秒\n",
    "# 2. 周、天\n",
    "# 3. 中国节日\n",
    "# 4. 国外特殊节日\n",
    "# 5. 农历、阳历\n",
    "# 6. 天干地支\n",
    "# 7. 二十四节气\n",
    "\n",
    "from pyunit_time import Time\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('这个月的第三个星期天')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('前2年的国庆节的后一天晚上8点半')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('上上个月')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('今天晚上8点')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('今年儿童节晚上九点一刻')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('今天中午十二点')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('明年春节')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('明年的感恩节')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('下3个星期1早上7点半')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('今年的大寒')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('2019年12月')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('8年前')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('三天以后')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('三天之内的下午3点')[0].get('keyDate'))\n",
    "\n",
    "print(Time('2023-9-15 20:15:00').parse('后三天的下午4点56秒')[0].get('keyDate'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "4b5adc7d-c8be-4770-ada0-97b55b49ccd8",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2014-12-12 10:55:50\n",
      "1991-05-17 00:00:00\n",
      "2023-11-16 11:33:58.549731\n",
      "2017-01-19 18:57:30\n",
      "2012-01-12 22:00:00-05:00\n",
      "2023-09-16 09:33:58.641416\n",
      "2014-10-12 00:00:00\n",
      "2014-12-10 00:00:00\n",
      "2024-09-16 11:33:58.651417\n",
      "1992-01-02 00:00:00\n"
     ]
    }
   ],
   "source": [
    "# 使用 dateparser 解析日期和时间\n",
    "\n",
    "import dateparser\n",
    "import datetime\n",
    "\n",
    "print(dateparser.parse('Fri, 12 Dec 2014 10:55:50'))\n",
    "\n",
    "print(dateparser.parse('1991-05-17'))\n",
    "\n",
    "print(dateparser.parse('In two months'))\n",
    "\n",
    "print(dateparser.parse('1484823450'))\n",
    "\n",
    "print(dateparser.parse('January 12, 2012 10:00 PM EST'))\n",
    "\n",
    "print(dateparser.parse('2小时前'))\n",
    "\n",
    "print(dateparser.parse('2014-10-12', settings={'DATE_ORDER': 'YMD'}))\n",
    "\n",
    "print(dateparser.parse('2014-10-12', settings={'DATE_ORDER': 'YDM'}))\n",
    "\n",
    "print(dateparser.parse('1 year', settings={'PREFER_DATES_FROM': 'future'}))\n",
    "\n",
    "print(dateparser.parse('tomorrow', settings={'RELATIVE_BASE': datetime.datetime(1992, 1, 1)}))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "95315a1c-1699-4bde-af7b-8bfdffef8b71",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "# jionlp - 微信公众号: JioNLP  Github: `https://github.com/dongrixinyu/JioNLP`.\n",
      "# jiojio - `http://www.jionlp.com/jionlp_online/cws_pos` is available for online trial.\n",
      "8月 : ['2023-08-01 00:00:00', '2023-08-31 23:59:59']\n",
      "中秋 : ['2023-09-29 00:00:00', '2023-09-29 23:59:59']\n",
      "国庆 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n",
      "2021年中秋节 : ['2021-09-21 00:00:00', '2021-09-21 23:59:59']\n",
      "9月21日 : ['2023-09-21 00:00:00', '2023-09-21 23:59:59']\n",
      "星期二 : ['2023-09-12 00:00:00', '2023-09-12 23:59:59']\n",
      "中秋节前 : ['2023-09-16 11:33:58', '2023-09-29 23:59:59']\n",
      "9月18日（星期六） : ['2023-09-18 00:00:00', '2023-09-18 23:59:59']\n",
      "9月19日至21日 : ['2023-09-19 00:00:00', '2023-09-21 23:59:59']\n",
      "从周日开始 : ['2023-09-17 00:00:00', 'inf']\n",
      "3天 : {'day': 3.0}\n",
      "中秋节后 : ['2023-09-29 00:00:00', 'inf']\n",
      "10天 : {'day': 10.0}\n",
      "国庆 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n"
     ]
    }
   ],
   "source": [
    "# 使用 jionlp 解析日期和时间（功能非常强大的中文 NLP 库）\n",
    "\n",
    "import time\n",
    "import jionlp as jio\n",
    "import json\n",
    "\n",
    "# 时间类型实体识别\n",
    "text = '''\n",
    "        8月临近尾声，中秋、国庆两个假期已在眼前。2021年中秋节是9月21日，星期二。\n",
    "        有不少小伙伴翻看放假安排后，发现中秋节前要\"补\"假。\n",
    "        记者注意到，根据放假安排，9月18日（星期六）上班，9月19日至21日放假调休，也就是从周日开始放假3天。\n",
    "        由于中秋节后上班不到 10天，又将迎来一个黄金周—国庆长假，因此工作也就\"安排\"上了。\n",
    "        双节来袭，仍有人要坚守岗位。\n",
    "       '''\n",
    "res = jio.ner.extract_time(text, time_base=time.time(), with_parsing=False)\n",
    "# print(json.dumps(res, ensure_ascii=False, indent=4, separators=(',', ':')))\n",
    "\n",
    "\n",
    "# 时间语义解析\n",
    "time_text_list = [x.get('text') for x in res]\n",
    "for time_text in time_text_list:\n",
    "    print(time_text,\":\",jio.parse_time(time_text, time_base=time.time()).get('time'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "17b19a01-db15-4295-a41d-9a2e406a5947",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1;36m原始语句：\u001b[0m 今天下午五点，我花了一个半小时走了五公里的路程。\n",
      "\u001b[1;36m解析语句：\u001b[0m \u001b[4;32m2023-09-16 17:00:58\u001b[0m，我花了\u001b[4;32m5400.0s\u001b[0m走了\u001b[4;32m5000.0m\u001b[0m的路程。\n",
      "['2023-09-16 17:00:58']\n"
     ]
    }
   ],
   "source": [
    "# 使用 sinan 解析日期和时间（中文日期 / 时间 / 数字量提取工具）\n",
    "\n",
    "from sinan import Sinan\n",
    "\n",
    "si = Sinan('今天下午五点，我花了一个半小时走了五公里的路程。')\n",
    "print(si.parse().get('datetime'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "037da7e8-b8e3-4302-9b36-f937b124861a",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['2023-09-11', '2023-09-16']\n"
     ]
    }
   ],
   "source": [
    "# 使用 timeworker 解析日期和时间（中文日期标准化库）\n",
    "\n",
    "import timeworker\n",
    "time_str = '最近五天'\n",
    "print(timeworker.parse(time_str))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a4a22222-da42-4bdf-aaf0-7713e6b40167",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "接下来进入地狱级难度测试环节！\n",
      "\n",
      "第1条测试文本是：11,10,2021 15:15:22 pm \n",
      "pyunit-time 解析的结果是： 报错，无法解析！\n",
      "dateparser 解析的结果是： None\n",
      "jionlp 解析的结果是：\n",
      "15:15:22 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n",
      "\u001b[1;36m原始语句：\u001b[0m 11,10,2021 15:15:22 pm \n",
      "\u001b[1;36m解析语句：\u001b[0m 11,10,2021 \u001b[4;32m2023-09-16 15:15:22\u001b[0m pm \n",
      "sinan 解析的结果是： ['2023-09-16 15:15:22']\n",
      "timeworker 解析的结果是： []\n",
      "\n",
      "\n",
      "第2条测试文本是：2022,10月, /.13      135:50:02 am\n",
      "pyunit-time 解析的结果是： 报错，无法解析！\n",
      "dateparser 解析的结果是： None\n",
      "jionlp 解析的结果是：\n",
      "50:02 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n",
      "\u001b[1;36m原始语句：\u001b[0m 2022,10月, /.13      135:50:02 am\n",
      "\u001b[1;36m解析语句：\u001b[0m 2022,\u001b[4;32m2023-10-16 11:34:00\u001b[0m, /.13      13\u001b[4;32m2023-09-16 05:50:02\u001b[0m am\n",
      "sinan 解析的结果是： ['2023-10-16 11:34:00', '2023-09-16 05:50:02']\n",
      "timeworker 解析的结果是： ['2023-10-01', '2023-10-31']\n",
      "\n",
      "\n",
      "第3条测试文本是：Publishd 公元2002年，10月， /·12   06：50：33 PM 时间\n",
      "pyunit-time 解析的结果是： 报错，无法解析！\n",
      "dateparser 解析的结果是： None\n",
      "jionlp 解析的结果是：\n",
      "2002年 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n",
      "10月 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n",
      "06：50：33 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n",
      "\u001b[1;36m原始语句：\u001b[0m Publishd 公元2002年，10月， /·12   06：50：33 PM 时间\n",
      "\u001b[1;36m解析语句：\u001b[0m Publishd 公元2002年，\u001b[4;32m2023-10-16 11:34:00\u001b[0m， /·12   06：50：33 PM 时间\n",
      "sinan 解析的结果是： ['2023-10-16 11:34:00']\n",
      "timeworker 解析的结果是： ['2002-10-01', '2002-10-31']\n",
      "\n",
      "\n",
      "第4条测试文本是：公元2002年.13+七月,5:18 PM\n",
      "pyunit-time 解析的结果是： 报错，无法解析！\n",
      "dateparser 解析的结果是： None\n",
      "jionlp 解析的结果是：\n",
      "2002年 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n",
      "5:18 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n",
      "\u001b[1;36m原始语句：\u001b[0m 公元2002年.13+七月,5:18 PM\n",
      "\u001b[1;36m解析语句：\u001b[0m 公元2002年.13+\u001b[4;32m2023-07-16 11:34:00\u001b[0m,\u001b[4;32m2023-09-16 05:18:00\u001b[0m PM\n",
      "sinan 解析的结果是： ['2023-07-16 11:34:00', '2023-09-16 05:18:00']\n",
      "timeworker 解析的结果是： ['2002-07-01', '2002-07-31']\n",
      "\n",
      "\n",
      "第5条测试文本是：1987年/10月/-11号.5:20 下午\n",
      "pyunit-time 解析的结果是： 报错，无法解析！\n",
      "dateparser 解析的结果是： None\n",
      "jionlp 解析的结果是：\n",
      "1987年 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n",
      "5:20 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n",
      "下午 : ['2023-10-01 00:00:00', '2023-10-01 23:59:59']\n",
      "\u001b[1;36m原始语句：\u001b[0m 1987年/10月/-11号.5:20 下午\n",
      "\u001b[1;36m解析语句：\u001b[0m 1987年/\u001b[4;32m2023-10-16 11:34:00\u001b[0m/-\u001b[4;32m2023-09-11 11:34:00\u001b[0m.\u001b[4;32m2023-09-16 05:20:00\u001b[0m \u001b[4;32m2023-09-16 15:34:00\u001b[0m\n",
      "sinan 解析的结果是： ['2023-10-16 11:34:00', '2023-09-11 11:34:00', '2023-09-16 05:20:00', '2023-09-16 15:34:00']\n",
      "timeworker 解析的结果是： ['1987-10-11', '1987-10-11']\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 地狱难度测试\n",
    "\n",
    "test_texts = ['11,10,2021 15:15:22 pm ','2022,10月, /.13      135:50:02 am','Publishd 公元2002年，10月， /·12   06：50：33 PM 时间','公元2002年.13+七月,5:18 PM','1987年/10月/-11号.5:20 下午']\n",
    "\n",
    "n = 1\n",
    "print('接下来进入地狱级难度测试环节！\\n')\n",
    "for test_text in test_texts:\n",
    "    print(f'第{n}条测试文本是：{test_text}')\n",
    "    try:\n",
    "        print('pyunit-time 解析的结果是：',Time('2023-9-15 20:15:00').parse('test_text')[0].get('keyDate'))\n",
    "    except:\n",
    "        print('pyunit-time 解析的结果是：','报错，无法解析！')\n",
    "    print('dateparser 解析的结果是：',dateparser.parse(test_text))\n",
    "    res2 = jio.ner.extract_time(test_text, time_base=time.time(), with_parsing=False)\n",
    "    time_text_list2 = [x.get('text') for x in res2]\n",
    "    print('jionlp 解析的结果是：')\n",
    "    for time_text2 in time_text_list2:\n",
    "        print(time_text2,\":\",jio.parse_time(time_text, time_base=time.time()).get('time'))\n",
    "    si = Sinan(test_text)\n",
    "    print('sinan 解析的结果是：',si.parse().get('datetime'))\n",
    "    print('timeworker 解析的结果是：',timeworker.parse(test_text))\n",
    "    print('\\n')\n",
    "    n += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "4885530b-ea11-481e-85a4-d8d7064b4d44",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2023-10-15 21:38:15\n",
      "1987-10-11 00:00:00\n"
     ]
    }
   ],
   "source": [
    "# Tips:文本转日期时间格式\n",
    "\n",
    "from datetime import datetime\n",
    "\n",
    "text1 = '2023-10-15 21:38:15'\n",
    "text2 = '1987-10-11'\n",
    "\n",
    "# 转换为日期时间格式\n",
    "print(datetime.strptime(text1, '%Y-%m-%d %H:%M:%S'))\n",
    "print(datetime.strptime(text2, '%Y-%m-%d'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "5ebb1638-664e-4ddc-85c9-013a9fbd82ea",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最近两周 : ['2023-09-02 00:00:00', '2023-09-16 11:34:01']\n",
      "构造出的日期区间序列是：\n",
      "           日期\n",
      "0  2023-09-02\n",
      "1  2023-09-03\n",
      "2  2023-09-04\n",
      "3  2023-09-05\n",
      "4  2023-09-06\n",
      "5  2023-09-07\n",
      "6  2023-09-08\n",
      "7  2023-09-09\n",
      "8  2023-09-10\n",
      "9  2023-09-11\n",
      "10 2023-09-12\n",
      "11 2023-09-13\n",
      "12 2023-09-14\n",
      "13 2023-09-15\n",
      "14 2023-09-16\n"
     ]
    }
   ],
   "source": [
    "# 在 pandas 中操作日期时间\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "# 更改列的类型为日期时间格式\n",
    "# df['日期时间'] = df['日期时间'].astype('datetime64')\n",
    "# 或者\n",
    "# df['日期时间'] = pd.to_datetime(df['日期时间'])\n",
    "\n",
    "# 以 jionlp 为构例，指定开始日期和结束日期，使用 pandas 构造日期区间序列\n",
    "time_text3 = '最近两周'\n",
    "print(time_text3,\":\",jio.parse_time(time_text3, time_base=time.time()).get('time'))\n",
    "start_date = jio.parse_time(time_text3, time_base=time.time()).get('time')[0]\n",
    "end_date = jio.parse_time(time_text3, time_base=time.time()).get('time')[1]\n",
    "date_generated = pd.date_range(start_date, end_date, freq='D') # 按天构造\n",
    "df = pd.DataFrame({'日期': date_generated}) # 将 DatetimeIndex 转换成 DataFrame\n",
    "print(f'构造出的日期区间序列是：\\n{df}')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
